#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->label1->setText("二叉树括号序列:");
    ui->label2->setText("森林括号序列:");
    ui->BinaryTreeInput->setPlaceholderText("输入二叉树括号序列");
    ui->ForestInput->setPlaceholderText("输入森林括号序列");
    ui->ConvertButton->setText("转换");
    ui->DrawButton->setText("可视化二叉树");

    ui->IsBinaryTree2Forest->setChecked(true);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_IsBinaryTree2Forest_stateChanged(int arg1)
{
    if (arg1 == 2) {
        ui->IsBinaryTree2Forest->setText("当前为二叉树转换至森林");

        ui->BinaryTreeInput->setReadOnly(false);
        ui->ForestInput->setReadOnly(true);
    }
    else {
        ui->IsBinaryTree2Forest->setText("当前为森林转换至二叉树");

        ui->BinaryTreeInput->setReadOnly(true);
        ui->ForestInput->setReadOnly(false);
    }
}

// 检查输入串中括号是否匹配
bool CheckParenthesis(QString str) {
    int stack = 0;
    for (int i = 0; i < str.length(); i++) {
        if (str[i] == '(') {
            stack++;
        }
        if (str[i] == ')') {
            stack--;
            if (stack < 0) {
                return false;
            }
        }
    }
    return stack == 0 ? true : false;
}

// 检查二叉树中每个配对的括号内是否只有一个逗号
bool CheckBranch(QString str) {
    if (str == "" || str.length() == 1) {
        return true;
    }
    if (str[1] != '(') {
        return false;
    }
    str = str.mid(2, str.length() - 3);

    // 用于括号匹配的栈
    int parenthesesCnt = 0;
    QString left = "", right = "";
    for (int i = 0; i <= str.length(); i++) {
        if (i == str.length()) {
            left = str;
            break;
        }
        if (str[i] == '(') {
            parenthesesCnt++;
        }
        else if (str[i] == ')') {
            parenthesesCnt--;
        }
        else if (str[i] == ',') {
            if (parenthesesCnt == 0) {
                left = str.left(i);
                right = str.right(str.length() - i - 1);
                break;
            }
        }
    }
    return CheckBranch(left) && CheckBranch(right);
}

// 检查有没有多字符组成节点
bool CheckAlpha(QString str) {
    auto IsInCharSet = [&](QChar ch)->bool {
        return ch == '(' || ch == '}' || ch == ',';
    };
    for (int i = 0; i < str.length() - 1; i++) {
        if (IsInCharSet(str[i]) && IsInCharSet(str[i + 1])) {
            return false;
        }
    }
    return true;
}

void MainWindow::on_ConvertButton_clicked()
{
    // 检查输入合法性(括号是否匹配,二叉树分支是否正确,字符是否为单个)
    if (ui->IsBinaryTree2Forest->isChecked()) {
        if (ui->BinaryTreeInput->text() == "") {
            return;
        }
        if (!CheckParenthesis(ui->BinaryTreeInput->text()) || !CheckBranch(ui->BinaryTreeInput->text()) || !CheckAlpha(ui->BinaryTreeInput->text())) {
            ui->BinaryTreeInput->setText("输入非法!");
            ui->ForestInput->setText("");
            return;
        }
        Tree binary_tree(true, ui->BinaryTreeInput->text());
        Forest forest;
        BinaryTree2Forest(binary_tree, forest);
        ui->ForestInput->setText(QString(forest.ToParenthesisString()));
    }
    else {
        if (ui->ForestInput->text() == "") {
            return;
        }
        if (!CheckParenthesis(ui->ForestInput->text()) || !CheckAlpha(ui->ForestInput->text())) {
            ui->ForestInput->setText("输入非法!");
            ui->BinaryTreeInput->setText("");
            return;
        }
        Forest forest(ui->ForestInput->text());
        Tree binary_tree;
        Forest2BinaryTree(forest, binary_tree);
        ui->BinaryTreeInput->setText(QString(binary_tree.ToParenthesisString()));
    }
}

void MainWindow::on_DrawButton_clicked()
{
    if (ui->BinaryTreeInput->text().length() == 0) {
        return;
    }
    Tree *tree = new Tree(true, ui->BinaryTreeInput->text());
    Painter *painter = new Painter(tree);
    painter->show();
}
